#pragma once
#include"Sem.hpp"
#include"Mutex.hpp"
#include<iostream>
#include<vector>
using namespace std;
using namespace semMoudle;
using namespace LockMoudle;

namespace ringBufferMoudle
{

    template <typename T>
    class ringBuffer
    {
    private:
        std::vector<T>  _ring; // cricle
        int _cap; // 总容量
        int _p_step; // 生产者的部署

        int _c_step; // 消费者的部署
        Sem _datasem; // 数据信号量
        Sem _spacesem; // 空间信号量
        // 现在想要现多生产多消费模型，就需要使用锁
        Mutex _c_lock;
        Mutex _p_lock;
    public:
        ringBuffer(int cap) :_ring(vector<T>(cap)), _cap(cap),
        _p_step(0), _c_step(0), _datasem(0), _spacesem(_cap)
        {

            // zdl:: 现在完成了信号量的初始化！！！
        }
        ~ringBuffer()
        {
            sem_destroy(_datasem.getPtr());
            sem_destroy(_spacesem.getPtr());
            // 多生产消费的互斥锁
        }
        void emplace(const T &in)
        {
            _spacesem.P();

            LockGuard lockguard(_p_lock);
            _ring[_p_step++] = in; // 此时生产完毕
            _p_step %= _cap; // 保持环形的特征

            _datasem.V();
        }
        void pop(T* out)
        {
            _datasem.P();

            LockGuard lockguard(_c_lock);
            *out = _ring[(_c_step)++];
            _c_step %= _cap;

            _datasem.V();
        }

    };
    

}